package ldh.im.fxbase.richtext;

import javafx.scene.Node;
import org.fxmisc.richtext.model.Codec;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public class TextItem<O extends TextItem> {

//    public static final String SPLIT_STRING = "|~|";
//    public static final String SPLIT_STRING2 = "\\|~\\|";

    public static final String SPLIT_STRING = "￼";
    public static final String SPLIT_REGEX = "￼[a-z]{1}\\{(.*)\\}"; // ￼|\|~\|  ￼e{dsafa}

    public Node createNode() {
        return null;
    }

    public TextItemType getTextItemType() {
        return null;
    }

    public String getStyle() {
        return "";
    }

    public boolean isNull() {
        return true;
    }

    public String getData() {
        return "";
    }

    public String getImData() {
        return TextItem.SPLIT_STRING + getTextItemType().getValue()  + "{" + getData() + "}";
    }

    public static <T extends TextItem> T parse(String content) {
        if (!content.startsWith(SPLIT_STRING)) return null;
        String pre = content.substring(1, 2);
        if (content.length() <= 3) return null;
        String data = content.substring(3, content.length()-1);
        try {
            TextItemType textItemType = TextItemType.parse(pre);
            if (textItemType != null) {
                return textItemType.newTextItem(data);
            }
        } catch (IllegalArgumentException i) {
            return null;
        }
        return null;
    }

    public static <O extends TextItem> Codec<O> createCodec() {
        return new Codec<O>() {

            @Override
            public String getName() {
                return "TextItem";
            }

            @Override
            public void encode(DataOutputStream os, O textItem) throws IOException {
                String content = textItem.getTextItemType() + ":" + textItem.getData();
                Codec.STRING_CODEC.encode(os, content);
            }

            @Override
            public O decode(DataInputStream is) throws IOException {
                String c = Codec.STRING_CODEC.decode(is);
                int split = c.indexOf(":");
                TextItemType type = TextItemType.parse(c.substring(0, split));
                return type.newTextItem(c.substring(split+1));
            }
        };
    }

    public static Codec<Void> createVoidCodec() {
        return new Codec<Void>() {

            @Override
            public String getName() {
                return "Void";
            }

            @Override
            public void encode(DataOutputStream os, Void v) throws IOException {

            }

            @Override
            public Void decode(DataInputStream is) throws IOException {
                return null;
            }
        };
    }

    public static Codec<String> createStringCodec() {
        return new Codec<String>() {

            @Override
            public String getName() {
                return "String";
            }

            @Override
            public void encode(DataOutputStream os, String v) throws IOException {
                if (v == null) {
                    os.write(0);
                    return;
                }
                byte[] bytes = v.getBytes("utf-8");
                os.write(bytes.length);
                os.write(bytes);
            }

            @Override
            public String decode(DataInputStream is) throws IOException {
                int l = is.read();
                if (l == 0) return "";
                byte[] bytes = new byte[l];
                is.read(bytes);
                return new String(bytes, "utf-8");
            }
        };
    }
}
